#ifndef GAMEENGINE_GRAPHICS_TEXTURE_TEXTURE_COORDINATES_H
#define GAMEENGINE_GRAPHICS_TEXTURE_TEXTURE_COORDINATES_H

#include <GameEngine/Graphics/graphics_settings.h>

#include <GameEngine/Graphics/Texture/texture_defs.h>

#include <vector>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif


//! Class in charge of holding generic texture coordinates available for multitexturing
/*!
 *  A texture coordinate is made of up to three float values,
 *  plus a texture index
 */
class _Graphics_decl TextureCoordinateMulti {

public:
	TextureCoordinateMulti(Texture::TextureIndex index = 0);
	TextureCoordinateMulti(float u, Texture::TextureIndex index = 0);
	TextureCoordinateMulti(float u, float v, Texture::TextureIndex index = 0);
	TextureCoordinateMulti(float u, float v, float w, Texture::TextureIndex index = 0);
	TextureCoordinateMulti(const TextureCoordinateMulti& rhs);
	TextureCoordinateMulti& operator=(const TextureCoordinateMulti& rhs);
	virtual ~TextureCoordinateMulti();

	void apply_coordinates() const;

protected:
	//! Texture index
	Texture::TextureIndex index_;

	//! Texture coordinates
	GAMEENGINE_DLL_CLASS_STD(vector,float) coordinates_;
};


//==============================================================================


//! Class in charge of holding 1D texture coordinates
/*!
 *  A 1D texture coordinate is made of one single float value
 */
class _Graphics_decl TextureCoordinate1d {

public:
	TextureCoordinate1d();
	TextureCoordinate1d(float u);
	TextureCoordinate1d(const TextureCoordinate1d& rhs);
	TextureCoordinate1d& operator=(const TextureCoordinate1d& rhs);
	virtual ~TextureCoordinate1d();

	void apply_coordinates(Texture::TextureIndex texture_index = 0) const;

	float u() const;
	float& u();

protected:
	//! Texture coordinate
	float u_;
};


//==============================================================================


//! Class in charge of holding 2D texture coordinates
/*!
 *  A 2D texture coordinate is made of two float values
 */
class _Graphics_decl TextureCoordinate2d {

public:
	TextureCoordinate2d();
	TextureCoordinate2d(float u, float v);
	TextureCoordinate2d(const TextureCoordinate2d& rhs);
	TextureCoordinate2d& operator=(const TextureCoordinate2d& rhs);
	virtual ~TextureCoordinate2d();

	void apply_coordinates(Texture::TextureIndex texture_index = 0) const;

	float u() const;
	float& u();
	float v() const;
	float& v();

protected:
	//! First texture coordinate
	float u_;

	//! Second texture coordinate
	float v_;
};


//==============================================================================


//! Class in charge of holding 3D texture coordinates
/*!
 *  A 3D texture coordinate is made of three float values
 */
class _Graphics_decl TextureCoordinate3d {

public:
	TextureCoordinate3d();
	TextureCoordinate3d(float u, float v, float w);
	TextureCoordinate3d(const TextureCoordinate3d& rhs);
	TextureCoordinate3d& operator=(const TextureCoordinate3d& rhs);
	virtual ~TextureCoordinate3d();

	void apply_coordinates(Texture::TextureIndex texture_index = 0) const;

	float u() const;
	float& u();
	float v() const;
	float& v();
	float w() const;
	float& w();

protected:
	//! First texture coordinate
	float u_;

	//! Second texture coordinate
	float v_;

	//! Third texture coordinate
	float w_;
};


#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#endif
